package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"log"
	"os"
	"strconv"
	"time"
)

// 实现一个辅助函数，将 uint64 转为 []byte，方便数据拼接
func Uint64ToByte(num uint64) []byte {
	var buffer bytes.Buffer
	err := binary.Write(&buffer, binary.BigEndian, num) // BigEndian大端对齐
	if err != nil {
		log.Panic(err)
	}
	return buffer.Bytes()
}

// TODO 委员会分配
func StartConfigs() {
	// a 配置创世区块时间戳
	genesisTimeStamp = uint64(time.Now().Unix())

	// 确定委员会内节点及委员会编号 【设定节点数目是委员会数目的倍数】
	relation := nodeNumber / committeeNum

	startNodeID, _ := strconv.Atoi(nodeStartNum)

	for i := 0; i < nodeNumber; i++ {
		committeeID := i/relation + 1
		committeeMemberInfo[committeeID] = append(committeeMemberInfo[committeeID], strconv.Itoa(startNodeID+i))
	}
}

// 1 记录微块重组【仅重组过程】
func miniToFullTime(nodeID string, timeStart int64) {
	filePath := MiNiToFullOnlyNew

	var f *os.File

	_, err := os.Stat(filePath)
	if err == nil {
		f, _ = os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	} else {
		f, _ = os.Create(filePath)
		f.WriteString("nodeID,timeSpeed,nodeNumber,committeeNum\n")
	}

	timeEnd := time.Now().UnixNano() // 纳秒

	// 纳秒转毫秒然后存储
	f.WriteString(
		nodeID + "," +
			strconv.Itoa(int((timeEnd-timeStart)/1e6)) +
			"," + strconv.Itoa(nodeNumber) +
			"," + strconv.Itoa(committeeNum) +
			"\n")
}


// 交易处理速度(考虑网络延迟)
func TransSpeed(receive, send string, startTime string) {
	filePath := transSpendFile

	var f *os.File

	_, err := os.Stat(filePath)
	if err == nil {
		f, _ = os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	} else {
		f, _ = os.Create(filePath)
		f.WriteString("receive,send,nodeNumber,committeeNum,roundMaxTrans,timeSpeed,tps\n")
	}

	start, _ := strconv.Atoi(startTime)
	timeEnd := time.Now().UnixNano() // 纳秒

	// 计算tps
	timeSpeed := (float64(timeEnd) - float64(start)) / 1e9 // 保持浮点数

	txs := maxTransNumPerRound / timeSpeed
	txsStr := fmt.Sprintf("%f", txs)

	// 纳秒转毫秒然后存储
	f.WriteString(
		receive + "," + // 接受微块节点
			send + "," + // 发送微块节点
			strconv.Itoa(nodeNumber) + "," + // 总节点数目
			strconv.Itoa(committeeNum) + "," + // 委员会数目
			strconv.Itoa(maxTransNumPerRound) + "," + // 每轮的最大交易数
			strconv.Itoa((int(timeEnd)-start)/1e6) + "," + // 微块重组时间（全过程）
			txsStr + "\n", // 交易tps
	)
}


// 交易处理速度(不考虑网络延迟)
func TransSpeedNoDelay(nodeID string, timeStart int64) {
	filePath := transSpendFileNoDelay

	var f *os.File

	_, err := os.Stat(filePath)
	if err == nil {
		f, _ = os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	} else {
		f, _ = os.Create(filePath)
		f.WriteString("nodeID,nodeNumber,committeeNum,timeSpeed,txSpeed\n")
	}

	timeEnd := time.Now().UnixNano() // 纳秒

	// 计算tps
	timeSpeed := (float64(timeEnd) - float64(timeStart)) / 1e9 // 保持浮点数

	txs := maxTransNumPerRound / timeSpeed

	txsStr := fmt.Sprintf("%f", txs)

	// 纳秒转毫秒然后存储
	f.WriteString(
		nodeID + "," +  // 节点编号
			strconv.Itoa(nodeNumber) +  // 节点数目
			"," + strconv.Itoa(committeeNum) +  // 委员会数目
			"," + strconv.Itoa((int(timeEnd)-int(timeStart))/1e6) +  // 花费时间ns
			"," + txsStr + "\n",  // 交易处理速度 
		)
}